/**
 * @file swei_config.c
 * @brief
 * @author  ()
 * @version 1.0
 * @date 2024-09-13
 *
 * @copyright Copyright (C) 2019 Queclink Wireless Solutions (ShenZhen) Co., Ltd. All Rights Reserved.
 *
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2024-09-13 <td>1.0     <td>     <td>内容
 * </table>
 */
#include "elog.h"
#include "include/port/swei_log.h"
#include "service/include/swei_cache.h"

#include "include/swei_config.h"
#include "include/port/swei_wrapper.h"
#include "include/swei_common.h"

#include "include/swei_downlink.h"
#include "include/swei_package.h"
#include "include/swei_login.h"
#include "include/swei_cmd.h"
#include "global.h"
#include "gsensor/gsensor.h"
#include "task/comm/co_heartbeat.h"
#include "flash/flash_main.h"
#include "flash/protocol_params/protocol_params.h"
#include "math.h"
#include "drivers/sensor/sensor_support.h"


/* 专用于swei_config_deal_cmd中检查数据长度最低要求的 */
#define CHECK_DATA_MIN_LEN(__min_len)                              \
    do {                                                           \
        if (data_len < (__min_len)) {                              \
            log_e("data length not enough! [len : %d]", data_len); \
            return CMD_FAILURE;                                    \
        }                                                          \
    } while (0)

static platform_config_param_st plat_conf;

/************* Forward decleration ***********/
static void swei_config_set_default(void);
int32_t save_platform_config(platform_config_param_st *param);


/**
 * @brief 平台用户配置参数恢复出厂设置
 * @note: 不修改固定的配置, 例如报文上报间隔
 */
static void platform_user_config_factory_reset(void)
{
    platform_config_param_st cfg = {0};
    
    /* 加载之前的配置信息 */
    memcpy(&cfg, &plat_conf, sizeof(platform_config_param_st));

    /* 清除用户配置并加载默认配置 */
    swei_config_set_default();

    /* 设置回之前的配置(UID和激活状态, 以及一些非用户配置不可以清空) */
    plat_conf.userId    = cfg.userId;
    plat_conf.activated = cfg.activated;
    memcpy(&plat_conf.gsensor_manager, &cfg.gsensor_manager, sizeof(gsensor_manager_st));
    memcpy(&plat_conf.gsensor_driver, &cfg.gsensor_driver, sizeof(gsensor_driver_st));
    memcpy(&plat_conf.common.rpt_conf, &cfg.common.rpt_conf, sizeof(rpt_intval_st));

    /* 保存当前配置 */
    save_platform_config(&plat_conf);
    log_i("reset platform config success.\r\n");
}

/**
 * @description: 恢复出厂测试
 * @param {int32_t} param
 * @param {void} *show_buf
 * @return {*}
 * @Date: 2023-11-11 10:46:49
 * @modification:
 */
static int32_t restore_device(int32_t delay_reboot_ms)
{
    // 1. 恢复默认参数
   platform_user_config_factory_reset();

    // 2. 重启设备
    return swei_system_restore(delay_reboot_ms);
}

/**
 * @brief 读取平台参数
 * @return int32_t
 */

unsigned char get_sensor_sample_frequecy_2_level(uint16_t freq)
{
    unsigned ret = 8;
    switch(freq) {
        case 100:
            ret = 8;
        break;
        case 200:
            ret = 9;
        break;
        case 400:
            ret = 10;
        break;

        default:
        break;
    }

    return ret;
}

unsigned short get_sensor_sample_level_2_frequecy(uint8_t level)
{
    unsigned ret = 100;
    switch(level) {
        case 8:
            ret = 100;
        break;
        case 9:
            ret = 200;
        break;
        case 10:
            ret = 400;
        break;

        default:
        break;
    }

    return ret;
}


/**
 * @brief 读取平台配置参数
 * @param  force_default 1强制加载平台默认参数 0读取flash存储参数
 * @return int32_t 
 */
int32_t load_platform_config(char force_default)
{
    platform_config_param_st param;
    int32_t res = 0;

    ST_GSENSOR_MNG_THRSHOLID *tilt_run = get_gsensor_tilt_run_config();
    ST_GSENSOR_MNG_THRSHOLID *overturn_run = get_gsensor_overturn_run_config();
    ST_GSENSOR_DRIVER_PARA *gs_local_run = get_gsensor_local_run_config();

    /*先初始化相关默认参数*/
    gsensor_module_init_prara();

    res = config_get(CONFIG_ID_PLAT, &param);

    if (res && VALID_FILA_VAL == param.valid_file_flag && (0 == force_default)) {
        memcpy(&plat_conf, &param, sizeof(platform_config_param_st));

        tilt_run->acc = plat_conf.gsensor_manager.tilt_acc;  //mg
        tilt_run->time = plat_conf.gsensor_manager.tilt_time;
        tilt_run->gyro = plat_conf.gsensor_manager.tilt_gyro;
        tilt_run->vel = plat_conf.gsensor_manager.tilt_val;  //km/h

        overturn_run->acc = plat_conf.gsensor_manager.over_acc;  //mg
        overturn_run->time = plat_conf.gsensor_manager.over_time;
        overturn_run->gyro = plat_conf.gsensor_manager.over_gyro;
        overturn_run->vel = plat_conf.gsensor_manager.over_val; //km/h

        gs_local_run->interrupt_sensitivity = plat_conf.gsensor_driver.interrupt_threshold;
        gs_local_run->tremos_sensitivity = plat_conf.common.shake_sensitivity;
        gs_local_run->measure_range = plat_conf.gsensor_driver.measure_range;
        if( (plat_conf.gsensor_driver.sample_frequecy >= 8) && (plat_conf.gsensor_driver.sample_frequecy <= 10) ) {
            gs_local_run->sample_frequecy = get_sensor_sample_level_2_frequecy(plat_conf.gsensor_driver.sample_frequecy);
        } else {

            gs_local_run->sample_frequecy = 100;
            plat_conf.gsensor_driver.sample_frequecy = 8;
            save_platform_config(&plat_conf); 
        }
        gs_local_run->reading_count = plat_conf.gsensor_driver.reading_count;
        gs_local_run->interval = plat_conf.gsensor_driver.thread_interval;

        gs_tremos_thresh_during_time = plat_conf.gsensor_manager.tremos_check_time;
        gs_unusual_moving_thresh_during_time = plat_conf.gsensor_manager.unusual_move_check_time;

        /* 内部参数变更同步 */
        gsensor_app_driver_param_sync();

        log_i("load platform config success.\r\n");

    
    } else {
    
        log_e("load platform config failed, set to default!\r\n");
        swei_config_set_default();

        plat_conf.gsensor_manager.tilt_acc = (uint32_t)(tilt_run->acc);  //mg
        plat_conf.gsensor_manager.tilt_time = tilt_run->time;
        plat_conf.gsensor_manager.tilt_gyro = tilt_run->gyro;
        plat_conf.gsensor_manager.tilt_val = tilt_run->vel; //km/h

        plat_conf.gsensor_manager.over_acc = (uint32_t)(overturn_run->acc);  //mg
        plat_conf.gsensor_manager.over_time = overturn_run->time;
        plat_conf.gsensor_manager.over_gyro = overturn_run->gyro;
        plat_conf.gsensor_manager.over_val = overturn_run->vel; //km/h

        plat_conf.gsensor_driver.interrupt_threshold = gs_local_run->interrupt_sensitivity;
        plat_conf.gsensor_driver.measure_range = gs_local_run->measure_range;
        plat_conf.gsensor_driver.sample_frequecy = get_sensor_sample_frequecy_2_level(gs_local_run->sample_frequecy);
        plat_conf.gsensor_driver.reading_count = gs_local_run->reading_count;
        plat_conf.gsensor_driver.thread_interval = gs_local_run->interval;

        plat_conf.common.shake_sensitivity = gs_local_run->tremos_sensitivity;

        plat_conf.gsensor_manager.tremos_check_time = gs_tremos_thresh_during_time;
        plat_conf.gsensor_manager.unusual_move_check_time = gs_unusual_moving_thresh_during_time;
        
        save_platform_config(&plat_conf);
    }

    /* Gsensor硬件实际设置在sensor线程延后进行 */
    gsensor_thresh_print();

    return SUCC;
}

#include <stdio.h>
#define fmt_str(id_fmt, val_fmt) "\t|\t" id_fmt "\t\t|\t  " val_fmt "\t\t\t|\t  " val_fmt "\t\t\t|\r\n"
/**
 * @description: 显示平台配置数据
 * @param {int32_t} param
 * @param {void} *show_buf
 * @return {*}
 * @Date: 2023-10-17 17:26:36
 * @modification:
 */
static void show_platform_config(void)
{
    platform_config_param_st ram_config;
    platform_config_param_st flash_config;

    memset(&ram_config, 0, sizeof(ram_config));
    memset(&flash_config, 0, sizeof(flash_config));
    memcpy(&ram_config, &plat_conf, sizeof(ram_config));

    config_get(CONFIG_ID_PLAT, &flash_config);

    // show the config in ram
    log_v("\r\n\t\t-----------------------    platform config param    -----------------------------\r\n\n"
          "\t|\tparam_id           \t\t|\t    ram\t\t\t|       flash\t\t\t|\r\n");
    log_v(fmt_str("%12s", "%5d"), "userId                 ", ram_config.userId, flash_config.userId);
    log_v(fmt_str("%12s", "%5d"), "find_bike              ", ram_config.find_bike, flash_config.find_bike);
    log_v(fmt_str("%12s", "%5d"), "shake_sensitivity      ", ram_config.common.shake_sensitivity, flash_config.common.shake_sensitivity);
    log_v(fmt_str("%12s", "%5d"), "ble_distance           ", ram_config.common.ble_distance, flash_config.common.ble_distance);
    log_v(fmt_str("%12s", "%5d"), "ble_insen_unlock       ", ram_config.common.ble_insen_unlock, flash_config.common.ble_insen_unlock);
    log_v(fmt_str("%12s", "%5d"), "sound_status           ", ram_config.common.sound_status, flash_config.common.sound_status);
    log_v(fmt_str("%12s", "%5d"), "sound_volume           ", ram_config.common.sound_volume, flash_config.common.sound_volume);
    log_v(fmt_str("%12s", "%5d"), "power_on_sound         ", ram_config.common.power_on_sound.status, flash_config.common.power_on_sound.status);
    log_v(fmt_str("%12s", "%s"), "power_on_sound.url     ", ram_config.common.power_on_sound.url, flash_config.common.power_on_sound.url);
    log_v(fmt_str("%12s", "%5d"), "power_off_sound        ", ram_config.common.power_off_sound.status, flash_config.common.power_off_sound.status);
    log_v(fmt_str("%12s", "%s"), "power_off_sound.url    ", ram_config.common.power_off_sound.url, flash_config.common.power_off_sound.url);
    log_v(fmt_str("%12s", "%5d"), "find_bike_sound        ", ram_config.common.find_bike_sound.status, flash_config.common.find_bike_sound.status);
    log_v(fmt_str("%12s", "%s"), "find_bike_sound.url    ", ram_config.common.find_bike_sound.url, flash_config.common.find_bike_sound.url);
    log_v(fmt_str("%12s", "%5d"), "ride_abnormal_sound    ", ram_config.common.ride_abnormal_sound.status, flash_config.common.ride_abnormal_sound.status);
    log_v(fmt_str("%12s", "%s"), "ride_abnormal_sound.url", ram_config.common.ride_abnormal_sound.url, flash_config.common.ride_abnormal_sound.url);
    log_v(fmt_str("%12s", "%5d"), "charger_link_sound     ", ram_config.common.charger_link_sound.status, flash_config.common.charger_link_sound.status);
    log_v(fmt_str("%12s", "%s"), "charger_link_sound.url ", ram_config.common.charger_link_sound.url, flash_config.common.charger_link_sound.url);
    log_v(fmt_str("%12s", "%5d"), "low_power_sound        ", ram_config.common.low_power_sound, flash_config.common.low_power_sound);
    log_v(fmt_str("%12s", "%5d"), "battery_abnormal_sound ", ram_config.common.battery_abnormal_sound, flash_config.common.battery_abnormal_sound);
    log_v(fmt_str("%12s", "%5d"), "shift_sound            ", ram_config.common.shift_sound, flash_config.common.shift_sound);
    log_v(fmt_str("%12s", "%5d"), "motor_supersonic_sound ", ram_config.common.motor_supersonic_sound, flash_config.common.motor_supersonic_sound);
    log_v(fmt_str("%12s", "%5d"), "ble_match_sound        ", ram_config.common.ble_match_sound, flash_config.common.ble_match_sound);
    log_v(fmt_str("%12s", "%5d"), "buttery2_link_sound    ", ram_config.common.buttery2_link_sound, flash_config.common.buttery2_link_sound);
    log_v(fmt_str("%12s", "%5d"), "in_ele_fance_sound     ", ram_config.common.in_ele_fance_sound, flash_config.common.in_ele_fance_sound);
    log_v(fmt_str("%12s", "%5d"), "out_ele_fance_sound    ", ram_config.common.out_ele_fance_sound, flash_config.common.out_ele_fance_sound);
    log_v(fmt_str("%12s", "%5d"), "christmas_sound        ", ram_config.common.christmas_sound.status, flash_config.common.christmas_sound.status);
    log_v(fmt_str("%12s", "%s"), "christmas_sound.url    ", ram_config.common.christmas_sound.url, flash_config.common.christmas_sound.url);
    log_v(fmt_str("%12s", "%5d"), "thanksgiving_sound     ", ram_config.common.thanksgiving_sound.status, flash_config.common.thanksgiving_sound.status);
    log_v(fmt_str("%12s", "%s"), "thanksgiving_sound.url ", ram_config.common.thanksgiving_sound.url, flash_config.common.thanksgiving_sound.url);
    log_v(fmt_str("%12s", "%5d"), "birthday_sound         ", ram_config.common.birthday_sound.status, flash_config.common.birthday_sound.status);
    log_v(fmt_str("%12s", "%s"), "birthday_sound.url     ", ram_config.common.birthday_sound.url, flash_config.common.birthday_sound.url);
    log_v(fmt_str("%12s", "%5d"), "new_year_sound         ", ram_config.common.new_year_sound.status, flash_config.common.new_year_sound.status);
    log_v(fmt_str("%12s", "%s"), "new_year_sound.url     ", ram_config.common.new_year_sound.url, flash_config.common.new_year_sound.url);
    log_v(fmt_str("%12s", "%5d"), "sound_volume     ", ram_config.common.sound_volume, flash_config.common.sound_volume);
    // log_4param("[%d][%d][%d][%d]", gsensor_manager.tilt_acc, gsensor_manager.tilt_time,
    //                                     gsensor_manager.tilt_angle, gsensor_manager.tilt_val);
    // log_4param("[%d][%d][%d][%d]", gsensor_manager.over_acc, gsensor_manager.over_time,
    //                                     gsensor_manager.over_angle, gsensor_manager.over_val);
    // log_2param("[%d][%d]", gsensor_manager.unusual_move_check_time, gsensor_manager.unusual_move_check_time);
    // log_5param("[%d][%d][%d][%d][%d]", gsensor_driver.interrupt_threshold,
    //                         gsensor_driver.measure_range,
    //                         gsensor_driver.sample_frequecy,
    //                         gsensor_driver.reading_count,
    //                         gsensor_driver.thread_interval);
    log_v(fmt_str("%12s", "%8x"), "valid_file_flag        ", ram_config.valid_file_flag, flash_config.valid_file_flag);
    log_v("\r\n\r\n\t\t-----------------------    platform config end    -------------------------------\r\n\r\n\n");
}

#include "lettershell/shell.h"
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC | SHELL_CMD_DISABLE_RETURN),
                 show_platform_config,
                 show_platform_config,
                 call show_platform_config to displays the platform config info);

/**
 * @description: 更新配置文件
 * @param {platform_config_param_st} param
 * @return {*}
 * @Date: 2023-10-17 16:31:25
 * @modification:
 */
int32_t save_platform_config(platform_config_param_st *param)
{
    if (param)
        config_set(CONFIG_ID_PLAT, param);

    return 0;
}

// 默认参数值
static void swei_config_set_default(void)
{
    memset(&plat_conf, 0, sizeof(plat_conf));
    // 默认打开声音开关
    plat_conf.common.sound_status = 1;
    // 默认音量为5 档
    plat_conf.common.sound_volume = 5;
    // bug2853 默认关闭超速声音
    plat_conf.common.motor_supersonic_sound = 3;
    // 默认上报间隔
    plat_conf.common.rpt_conf.gps_rpt_intval = 10;
    plat_conf.common.rpt_conf.can_rpt_intval = 10;
    plat_conf.common.rpt_conf.can_rpt_intval2 = 30;
    plat_conf.common.rpt_conf.hbt_rpt_intval = 30;
    // 文件有效位
    plat_conf.valid_file_flag = VALID_FILA_VAL;
}

/**
 * @brief 获取用户ID
 * @return uint32_t
 */
uint32_t swei_config_get_userid(void)
{
    return plat_conf.userId;
}

/**
 * @brief 设置用户ID
 * @param  new_userid       My Param doc
 */
void swei_config_set_userid(uint32_t new_userid)
{
    plat_conf.userId = new_userid;

    // 更新文件
    save_platform_config(&plat_conf);
}

/**
 * @brief 平台配置数据上传间隔命令
 * @param  cmd_id           My Param doc
 * @param  cmd_opcode       My Param doc
 * @param  p_data           My Param doc
 * @param  data_len         My Param doc
 * @return DLCMD_RET_TYPE_ENUM
 */
static DLCMD_RET_TYPE_ENUM swei_config_intval_handler(DOWN_LINK_CMD_ENUM cmd_id, uint16_t cmd_opcode, const uint8_t *p_data, uint32_t data_len)
{
    if (data_len < 3) {
        return DLCMD_RET_ERROR;
    }

    /**
     * @todo heatbeat 配置可以合入swei_config_set中
     */
    uint32_t intval = (p_data[1] << 8) | p_data[2];
    int32_t ret = swei_config_rpt_intval_set((platform_config_id_e)p_data[0], intval); // 配置保存参数
    if (CMD_SUCCESS == ret) {
        save_platform_config(&plat_conf);
        return DLCMD_RET_FINISH;
    } else {
        return DLCMD_RET_ERROR;
    }
}

/**
 * @brief 下行恢复出厂指令处理函数
 * @param  cmd_id           My Param doc
 * @param  cmd_opcode       My Param doc
 * @param  p_data           My Param doc
 * @param  data_len         My Param doc
 * @return DLCMD_RET_TYPE_ENUM
 */
static DLCMD_RET_TYPE_ENUM swei_config_restore_handler(DOWN_LINK_CMD_ENUM cmd_id, uint16_t cmd_opcode, const uint8_t *p_data, uint32_t data_len)
{
    // 延时5s设备恢复出厂
    if (0 == restore_device(5000)) {
        // 上报指令应答
        swei_netProtocol_ack_downlink_cmd(cmd_id, CMD_SUCCESS, true); // 设备通用应答0x000B (0成功)
        return DLCMD_RET_CONTINUE;
    } else {
        return DLCMD_RET_ERROR;
    }
}

/**
 * @brief 平台下发指令设置gsensor震动报警灵敏度
 * @param  cmd_id           My Param doc
 * @param  cmd_opcode       My Param doc
 * @param  p_data           My Param doc
 * @param  data_len         My Param doc
 * @return DLCMD_RET_TYPE_ENUM
 */
DLCMD_RET_TYPE_ENUM swei_config_shake_handler(DOWN_LINK_CMD_ENUM cmd_id, uint16_t cmd_opcode, const unsigned char *p_data, uint32_t data_len)
{

    if (data_len < 1) return DLCMD_RET_ERROR;
    int var = (int)p_data[0];

    switch (var) {
        case 2:
            plat_conf.gsensor_driver.interrupt_threshold = EN_COLLIDE_EVENT_SENSITIVITY_HIGH;
            break;
        case 1:
            plat_conf.gsensor_driver.interrupt_threshold = EN_COLLIDE_EVENT_SENSITIVITY_MIDDLE;
            break;
        case 0:
            plat_conf.gsensor_driver.interrupt_threshold = EN_COLLIDE_EVENT_SENSITIVITY_LOW;
            break;
        default:
            log_e("set sensitivity value error, var:%d", var);
            break;
    }

    //! @todo: 设置并生效
    // tbox_gsensor_set_threshold(plat_conf.gsensor_driver.tremos_sensitivity);
    // log_i("set plat_conf.gsensor_driver.tremos_sensitivity =%d ", plat_conf.gsensor_driver.tremos_sensitivity);

    save_platform_config(&plat_conf);

    return DLCMD_RET_FINISH;
}

/**
 * @brief 平台下发指令设置监测相关阈值的回调函数
 * @param  cmd_id           My Param doc
 * @param  cmd_opcode       My Param doc
 * @param  p_data           My Param doc
 * @param  data_len         My Param doc
 * @return DLCMD_RET_TYPE_ENUM
 */
DLCMD_RET_TYPE_ENUM swei_config_snsr_mng_handler(DOWN_LINK_CMD_ENUM cmd_id, uint16_t cmd_opcode,
                                                 const unsigned char *p_data, uint32_t data_len)
{
    uint32_t tilt_acc = ((uint32_t)(p_data[0]) << 24 | (uint32_t)(p_data[1]) << 16 | (uint32_t)(p_data[2]) << 8 | (uint32_t)(p_data[3]));
    uint32_t over_acc = ((uint32_t)(p_data[7]) << 24 | (uint32_t)(p_data[8]) << 16 | (uint32_t)(p_data[9]) << 8 | (uint32_t)(p_data[10]));
    uint32_t unusual_move_check_time = ((uint16_t)(p_data[14]) << 8 | (uint16_t)(p_data[15]));
    uint32_t tremos_check_time = ((uint16_t)(p_data[16]) << 8 | (uint16_t)(p_data[17]));


    if (   !(300 < tilt_acc < 1610612736)\
        || !(0 < p_data[4] < 200)\
        || !(40 < p_data[5] < 90)\
        || !(3 < p_data[6] < 20)\
        || !(300 < over_acc < 1610612736)\
        || !(20 < p_data[11] < 200)\
        || !(3 < p_data[12] < 20)\
        || !(3 < p_data[13] < 20)\
        || !(0 < unusual_move_check_time < 600)\
        || !(0 < tremos_check_time < 1500)) {
            return DLCMD_RET_ERROR;
        }


    if (data_len != 18) {
        log_e("get gsensor manage threshold error");
    } else {
        /* 设置倾斜相关数值 */
        plat_conf.gsensor_manager.tilt_acc   = tilt_acc;
        plat_conf.gsensor_manager.tilt_time  = (uint8_t)(p_data[4]);
        plat_conf.gsensor_manager.tilt_gyro = (uint8_t)(p_data[5]);
        plat_conf.gsensor_manager.tilt_val   = (uint8_t)(p_data[6]);

        /*  设置翻转相关数值 */
        plat_conf.gsensor_manager.over_acc   = over_acc;
        plat_conf.gsensor_manager.over_time  = (uint8_t)(p_data[11]);
        plat_conf.gsensor_manager.over_gyro = (uint8_t)(p_data[12]);
        plat_conf.gsensor_manager.over_val   = (uint8_t)(p_data[13]);

        plat_conf.gsensor_manager.unusual_move_check_time = unusual_move_check_time;
        plat_conf.gsensor_manager.tremos_check_time = tremos_check_time;

        save_platform_config(&plat_conf);

        log_i("gsensor has set mng threshold from platform ");
    }

    return DLCMD_RET_FINISH;
}

/**
 * @brief 平台下行GSensor配置处理函数
 * @param  cmd_id           My Param doc
 * @param  cmd_opcode       My Param doc
 * @param  p_data           My Param doc
 * @param  data_len         My Param doc
 * @return DLCMD_RET_TYPE_ENUM
 */
DLCMD_RET_TYPE_ENUM swei_config_snsr_drv_handler(DOWN_LINK_CMD_ENUM cmd_id, uint16_t cmd_opcode, const unsigned char *p_data, uint32_t data_len)
{
    if (data_len != 6) {
        log_e("get gsensor driver threshold error");
    } else {
        plat_conf.gsensor_driver.thread_interval    = (uint8_t)(p_data[0]);
        plat_conf.gsensor_driver.measure_range      = (uint8_t)(p_data[1]);
        plat_conf.gsensor_driver.sample_frequecy    = (uint8_t)(p_data[2]);
        plat_conf.gsensor_driver.reading_count      = (uint8_t)(p_data[3]);

        /* 设置震动检测等级 */
        plat_conf.gsensor_driver.interrupt_threshold = ((uint16_t)(p_data[4]) << 8 | (uint16_t)(p_data[5]));

        log_i("gsensor has set threshold of driver setting from platform ");
    }

    return DLCMD_RET_FINISH;
}


/**
 * @brief 平台下行TBOX信息一键收集处理函数
 * @param  cmd_id           My Param doc
 * @param  cmd_opcode       My Param doc
 * @param  p_data           My Param doc
 * @param  data_len         My Param doc
 * @return DLCMD_RET_TYPE_ENUM
 */
DLCMD_RET_TYPE_ENUM swei_tbox_info_collect_handler(DOWN_LINK_CMD_ENUM cmd_id, uint16_t cmd_opcode, const unsigned char *p_data, uint32_t data_len)
{
    swei_config_report_start();
    return DLCMD_RET_FINISH;
}


/**
 * @description: 初始化
 * @return {*}
 * @Date: 2023-10-17 15:17:10
 * @modification:
 */
int32_t swei_config_init(void)
{
    // 1. read config from filesystem or flash
    load_platform_config(0);

    // 2. 显示系统配置信息 & show the system config info
    show_platform_config();

    // 3. 注册下行指令处理函数
    swei_downlink_cmd_register(DOWN_LINK_CMD_RESTORE, swei_config_restore_handler);
    swei_downlink_cmd_register(DOWN_LINK_CMD_SET_UPLOAD_TIME, swei_config_intval_handler);
    swei_downlink_cmd_register(DOWN_LINK_CMD_SHAKE_SENSITIVITY, swei_config_shake_handler);
    swei_downlink_cmd_register(DOWN_LINK_CMD_GSENSOR_MANERGE, swei_config_snsr_mng_handler);
    swei_downlink_cmd_register(DOWN_LINK_CMD_GSENSOR_DRIVER, swei_config_snsr_drv_handler);
    swei_downlink_cmd_register(DOWN_LINK_CMD_TBOX_INFO_COLLECT, swei_tbox_info_collect_handler);

    return 0;
}

/**
 * @description: 去除初始化
 * @return {*}
 * @Date: 2023-10-17 15:17:10
 * @modification:
 */
int32_t swei_config_deinit(void)
{
    // 1. write config to filesystem or flash

    return 0;
}

/**
 * @description: 读取配置参数
 * @return {*}
 * @Date: 2023-10-17 17:34:44
 * @modification:
 */
platform_config_param_st swei_config_get(void)
{
    return plat_conf;
}


/**
 * @description: 读取配置参数
 * @return {*}
 * @Date: 2023-10-17 17:34:44
 * @modification:
 */
common_config_st swei_config_common_get(void)
{
    return plat_conf.common;
}


/**
 * @description: 读取配置参数
 * @return {*}
 * @Date: 2023-10-17 17:34:44
 * @modification:
 */
rpt_intval_st swei_config_rpt_get(void)
{
    return plat_conf.common.rpt_conf;
}


/**
 * @brief 各种发送间隔获取
 * @param  flag             My Param doc
 * @return int32_t 
 */
int32_t swei_config_rpt_intval_get(platform_config_id_e flag)
{
    int32_t ret = -CMD_FAILURE;
    rpt_intval_st *conf = &plat_conf.common.rpt_conf;

    assert_ptr_ret(conf, -EPERM);

    switch (flag) {
        case CONFIG_GPSINFO_INTERVAL: // gps
            if (0 == conf->gps_rpt_intval) {
                conf->gps_rpt_intval = 10;
            }
            ret = conf->gps_rpt_intval;
            break;
        case CONFIG_CANINFO_INTERVAL1: // can状态信息周期1
            if (0 == conf->can_rpt_intval) {
                conf->can_rpt_intval = 10;
            }
            ret = conf->can_rpt_intval;
            break;
        case CONFIG_CANINFO_INTERVAL2: // can状态信息周期2
            if (0 == conf->can_rpt_intval2) {
                conf->can_rpt_intval2 = 30;
            }
            ret = conf->can_rpt_intval2;
            break;
        case CONFIG_HEARTBEAT_INTERVAL: // 心跳周期
            if (0 == conf->hbt_rpt_intval) {
                conf->hbt_rpt_intval = 30;
            }
            ret = conf->hbt_rpt_intval;
            break;
        default:
            log_e("type[%d] err!", flag);
            break;
    }

    return ret;
}

/**
 * @brief 各种发送间隔设置
 * @param  flag             My Param doc
 * @return int32_t 
 */
int32_t swei_config_rpt_intval_set(platform_config_id_e flag, uint32_t sec)
{
    int32_t ret = CMD_FAILURE;
    rpt_intval_st *conf = &plat_conf.common.rpt_conf;

    assert_ptr_ret(conf, -EPERM);

    switch (flag) {
        case CONFIG_GPSINFO_INTERVAL: // gps
            conf->gps_rpt_intval = sec;
            ret = CMD_SUCCESS;
            break;
        case CONFIG_CANINFO_INTERVAL1: // can状态信息周期1
            conf->can_rpt_intval = sec;
            ret = CMD_SUCCESS;
            break;
        case CONFIG_CANINFO_INTERVAL2: // can状态信息周期2
            conf->can_rpt_intval2 = sec;
            ret = CMD_SUCCESS;
            break;
        case CONFIG_HEARTBEAT_INTERVAL: // 心跳周期
            conf->hbt_rpt_intval = sec;
            ret = CMD_SUCCESS;
            break;
        default:
            log_e("type[%d] err!", flag);
            break;
    }

    return ret;
}


#include "misc/misc_system.h"
const rpt_intval_t report_send_interval[REPORT_TYPE_MAX] = 
{
    /*激活正常      激活休眠        非激活正常         非激活休眠  (S)*/

    {15,        180,       15,              180},   //REPORT_HEARTBEAT
    {10,        7200,       120,            0},   //REPORT_GPS
    {10,        7200,       120,            0},   //REPORT_LBS
#if SUPPORT_FOR_WIFI_UPLOAD
    {10,        7200,       120,            0},   //REPORT_WIFI
#else 
    {0,         0,          0,              0},   //REPORT_WIFI
#endif
    {30,       7200,       0,               0},   //REPORT_RSRP_SIGNAL
    {10,        0,          0,              0},   //REPORT_CAN_INFO_TYPE1
    {30,        0,          0,              0},   //REPORT_CAN_INFO_TYPE2
    {0,         7200,       0,                0},   //REPORT_TBOX_BATT     
};

#define NORMAL (0)
#define SLEEP  (1)
#define INACTIVE (0)
#define ACTIVE   (1)
#define ACTIVE_STATE_NORMAL     (NORMAL << 4 | ACTIVE)
#define ACTIVE_STATE_SLEEP      (SLEEP << 4 | ACTIVE)
#define INACTIVE_STATE_NORMAL   (NORMAL << 4 | INACTIVE)
#define INACTIVE_STATE_SLEEP    (SLEEP << 4 | INACTIVE)
uint32_t swei_config_rtp_intval_update(uint8_t type)
{
    uint8_t active = 0;             // 0 - 非激活; 1 - 激活
    uint8_t work = 0;                // 0 - 正常工作模式; 1 - 低功耗模式
    uint8_t state = 0;
    uint32_t rpt_config_intval = 0;

    active = misc_get_active_state();
    work   = misc_get_work_mode(); 
    state  = work << 4 | active; 

    if(state == ACTIVE_STATE_NORMAL) {
        /* 获取平台配置 */
        if (REPORT_GPS == type || REPORT_LBS == type || REPORT_WIFI == type)
            rpt_config_intval = swei_config_rpt_intval_get(CONFIG_GPSINFO_INTERVAL);    // LBS/GPS/WIFI
        if (REPORT_HEARTBEAT == type)
            rpt_config_intval = swei_config_rpt_intval_get(CONFIG_HEARTBEAT_INTERVAL);  // HBT
        if (REPORT_CAN_INFO_TYPE1 == type)
            rpt_config_intval = swei_config_rpt_intval_get(CONFIG_CANINFO_INTERVAL1);  // HBT
        if (REPORT_CAN_INFO_TYPE2 == type)
            rpt_config_intval = swei_config_rpt_intval_get(CONFIG_CANINFO_INTERVAL2);  // HBT

        return rpt_config_intval ? rpt_config_intval : report_send_interval[type].act_normal;
    } else if(state == ACTIVE_STATE_SLEEP) {
        return report_send_interval[type].act_sleep;
    } else if(state == INACTIVE_STATE_NORMAL) {
        return report_send_interval[type].inactive_normal;
    } else {    // if(state == INACTIVE_STATE_SLEEP) 
        return report_send_interval[type].inactive_sleep;
    } 
}



/**
 * @description: 处理相同的数据类型
 * @param {int32_t} min 合理值最小值
 * @param {int32_t} max 合理值最大值
 * @param {uint8_t} data 数据
 * @param {uint8_t} *change_var 修改值
 * @return {*}
 * @Date: 2023-10-24 16:35:40
 * @modification:
 */
static int32_t swei_deal_same_uint8_data(int32_t min, int32_t max, uint8_t data, uint8_t *change_var)
{
    int32_t ret = CMD_SUCCESS;
    if (data >= min && data <= max) {
        *change_var = data;
    } else {
        ret = CMD_FAILURE;
    }
    return ret;
}

extern errno_t memmove_s(void *dest, size_t destSize, const void *src, size_t count);
/**
 * @description: 处理相同的数据结构体
 * @param {int32_t} min 合理值最小值
 * @param {int32_t} max 合理值最大值
 * @param {uint8_t} data 数据
 * @param {uint8_t} *change_var 修改值
 * @return {*}
 * @Date: 2023-10-24 16:52:28
 * @modification:
 */
static int32_t swei_deal_same_download_addr_data(int32_t min, int32_t max, const uint8_t *data, short data_len, download_addr *change_var)
{
    int32_t ret = CMD_SUCCESS;
    if (data[0] >= min && data[0] <= max) {
        change_var->status = data[0];
    } else {
        ret = CMD_FAILURE;
    }
    if (data[0] == 2) {
        memmove_s(change_var->url, URL_MAX_LEN, data + 1, data_len - 1);
    }
    return ret;
}

/**
 * @description:Gsensor-manager配置信息
 * @param {uint8_t} *data
 * @return {*}
 * @Date: 2024-02-22 16:32:10
 * @modification:
 */
static int32_t swei_deal_gsensor_manager_data(const uint8_t *data)
{
    int32_t i                              = 0;
    plat_conf.gsensor_manager.tilt_acc = (data[i] << 24) | (data[i + 1] << 16) | (data[i + 2] << 8) | (data[i + 3]);
    i += 4;
    plat_conf.gsensor_manager.tilt_time  = data[i++];
    plat_conf.gsensor_manager.tilt_gyro = data[i++];
    plat_conf.gsensor_manager.tilt_val   = data[i++];

    plat_conf.gsensor_manager.over_acc = (data[i] << 24) | (data[i + 1] << 16) | (data[i + 2] << 8) | (data[i + 3]);
    i += 4;
    plat_conf.gsensor_manager.over_time  = data[i++];
    plat_conf.gsensor_manager.over_gyro = data[i++];
    plat_conf.gsensor_manager.over_val   = data[i++];

    plat_conf.gsensor_manager.unusual_move_check_time = (data[i] << 8) | data[i + 1];
    i += 2;
    plat_conf.gsensor_manager.tremos_check_time = (data[i] << 8) | data[i + 1];
    i += 2;

    return CMD_SUCCESS;
}
/**
 * @description:Gsensor-driver配置信息
 * @param {uint8_t} *data
 * @return {*}
 * @Date: 2024-02-22 16:32:10
 * @modification:
 */
static int32_t swei_deal_gsensor_driver_data(const uint8_t *data)
{
    if (data[2] > 10 || data[2] < 8)
        return CMD_FAILURE;

    int32_t i                                        = 0;
    plat_conf.gsensor_driver.interrupt_threshold = data[i++];
    plat_conf.gsensor_driver.measure_range       = data[i++];
    plat_conf.gsensor_driver.sample_frequecy     = data[i++];
    plat_conf.gsensor_driver.reading_count       = data[i++];
    plat_conf.gsensor_driver.thread_interval     = (data[i] << 8) | data[i + 1];

    return CMD_SUCCESS;
}

/**
 * @description: 处理下行配置数据
 * @param {short} cmd_id 指令id
 * @param {uint8_t} *data 数据内容
 * @param {short} data_len 数据长度
 * @return {int32_t}  CMD_SUCCESS: 数据保存成功;  CMD_FAILURE: 数据错误，保存失败;   ACK_UNSUPPORT: 此命令无需修改配置
 * @Date: 2023-10-19 09:12:30
 * @modification:
 */
int32_t swei_config_deal_cmd(uint16_t cmd_id, const uint8_t *data, short data_len)
{
    int32_t ret = CMD_SUCCESS;

    if ((data_len != 0 && data == NULL) || data_len > URL_MAX_LEN) {
        log_e("input data err! [len : %d]", data_len);
        return CMD_FAILURE;
    }
    if (cmd_id >= DOWN_LINK_CMD_NUM_MAX) {
        ret = CMD_FAILURE;
        return ret;
    }
    switch (cmd_id) {
        case DOWN_LINK_CMD_FIND_BIKE: // 寻车
            plat_conf.find_bike = 1;
            break;
        case DOWN_LINK_CMD_CLOSE_FIND_BIKE: // 关闭寻车
            plat_conf.find_bike = 0;
            break;
        case DOWN_LINK_CMD_SHAKE_SENSITIVITY: // 设置震动灵敏度 0 低 / 1 标准 / 2 高
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 2, data[0], &plat_conf.common.shake_sensitivity);
            if(ret == CMD_SUCCESS) {
                tbox_gsensor_set_threshold(plat_conf.common.shake_sensitivity);

                save_platform_config(&plat_conf);
            }
            break;
        case DOWN_LINK_CMD_BLE_DISTANCE: // 蓝牙感应距离设置 0 近 / 1 标准 / 2 远
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 2, data[0], &plat_conf.common.ble_distance);
            break;
        case DOWN_LINK_CMD_BLE_INSEN_UNLOCK: // 蓝牙无感解锁 0 关 / 1 开
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 1, data[0], &plat_conf.common.ble_insen_unlock);
            break;
        case DOWN_LINK_CMD_SOUND_STATUS: // 音效开关 0 关 / 1 开
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 1, data[0], &plat_conf.common.sound_status);
            break;
        case DOWN_LINK_CMD_SET_POWER_ON_SOUND: // 开机音效设置 0：音效1 / 1：音效2 / 2 自定义 / 3关闭声音
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_download_addr_data(0, 3, data, data_len, &plat_conf.common.power_on_sound);
            break;
        case DOWN_LINK_CMD_SET_POWER_OFF_SOUND: // 关机音效设置 0：音效1 / 1：音效2 / 2 自定义 / 3关闭声音
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_download_addr_data(0, 3, data, data_len, &plat_conf.common.power_off_sound);
            break;
        case DOWN_LINK_CMD_SET_FIND_BIKE_SOUND: // 寻车声音设置 0：音效1 / 1：音效2 / 2 自定义 / 3关闭声音
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_download_addr_data(0, 3, data, data_len, &plat_conf.common.find_bike_sound);
            break;
        case DOWN_LINK_CMD_SET_RIDE_ABNORMAL_SOUND: // 震动或骑行异常报警音设置 0：音效1 / 1：音效2 / 2 自定义 / 3关闭声音
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_download_addr_data(0, 3, data, data_len, &plat_conf.common.ride_abnormal_sound);
            break;
        case DOWN_LINK_CMD_SET_LOW_POWER_SOUND: // 电量低提醒设置 0：音效1 / 1：音效2
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 3, data[0], &plat_conf.common.low_power_sound);
            break;
        case DOWN_LINK_CMD_SET_BARRERY_ABNORMAL_SOUND: // 电池电控故障声音 0：音效1 / 1：音效2
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 3, data[0], &plat_conf.common.battery_abnormal_sound);
            break;
        case DOWN_LINK_CMD_SET_SHIFT_SOUND: // 换挡提示音 0：音效1 / 1：音效2
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 3, data[0], &plat_conf.common.shift_sound);
            break;
        case DOWN_LINK_CMD_SET_MOTOR_SUPERSONIC_SOUND: // 电机超速音 0：音效1 / 1：音效2
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 3, data[0], &plat_conf.common.motor_supersonic_sound);
            break;
        case DOWN_LINK_CMD_SET_TBOX_BIND_SOUND: // 绑定成功提示音 0：音效1 / 1：音效2
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 3, data[0], &plat_conf.common.ble_match_sound);
            break;
        case DOWN_LINK_CMD_SET_CHARGER_LINK_SOUND: // 充电器连接成功提示音 0：音效1 / 1：音效2 / 2 自定义  / 3关闭声音
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_download_addr_data(0, 3, data, data_len, &plat_conf.common.charger_link_sound);
            break;
        case DOWN_LINK_CMD_SET_BUTTERY2_LINK_SOUND: // 副电池接入成功提示音 0：音效1 / 1：音效2
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 3, data[0], &plat_conf.common.buttery2_link_sound);
            break;
        case DOWN_LINK_CMD_SET_IN_ELE_FANCE_SOUND: // 进入电子围栏提示音 0：音效1 / 1：音效2
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 3, data[0], &plat_conf.common.in_ele_fance_sound);
            break;
        case DOWN_LINK_CMD_SET_OUT_ELE_FANCE_SOUND: // 出电子围栏提示音 0：音效1 / 1：音效2
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(0, 3, data[0], &plat_conf.common.out_ele_fance_sound);
            break;
        case DOWN_LINK_CMD_SET_CHRISTMAS_SOUND: // 圣诞提示音 1 人声/2 自定义  / 3关闭声音
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_download_addr_data(1, 3, data, data_len, &plat_conf.common.christmas_sound);
            break;
        case DOWN_LINK_CMD_SET_THANKSGIVING_SOUND: // 感恩节提示音 1 人声/2 自定义 / 3关闭声音
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_download_addr_data(1, 3, data, data_len, &plat_conf.common.thanksgiving_sound);
            break;
        case DOWN_LINK_CMD_SET_BIRTHDAY_SOUND: // 生日提示音 1 人声/2 自定义 / 3关闭声音
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_download_addr_data(1, 3, data, data_len, &plat_conf.common.birthday_sound);
            break;
        case DOWN_LINK_CMD_SET_NEW_YEAR_SOUND: // 新年提示音 1 人声/2 自定义 / 3关闭声音
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_download_addr_data(1, 3, data, data_len, &plat_conf.common.new_year_sound);
            break;
        case DOWN_LINK_CMD_GSENSOR_MANERGE: // Gsensor-manerge设置
            CHECK_DATA_MIN_LEN(18);
            if (data_len == 18) // 结构体数据为18
            {
                ret = swei_deal_gsensor_manager_data(data);
            } else {
                ret = CMD_FAILURE;
            }
            if (ret == CMD_SUCCESS) {

                ST_GSENSOR_MNG_THRSHOLID *tilt_run = get_gsensor_tilt_run_config();

                tilt_run->acc = plat_conf.gsensor_manager.tilt_acc;  //300-1610612736mg
                tilt_run->time = plat_conf.gsensor_manager.tilt_time;
                tilt_run->gyro = plat_conf.gsensor_manager.tilt_gyro;
                tilt_run->vel = plat_conf.gsensor_manager.tilt_val;  //3-20km/h

                ST_GSENSOR_MNG_THRSHOLID *overturn_run = get_gsensor_overturn_run_config();

                overturn_run->acc = plat_conf.gsensor_manager.over_acc;  //300-1610612736mg
                overturn_run->time = plat_conf.gsensor_manager.over_time;
                overturn_run->gyro = plat_conf.gsensor_manager.over_gyro;
                overturn_run->vel = plat_conf.gsensor_manager.over_val;  //3-20 km/h

                gs_tremos_thresh_during_time = plat_conf.gsensor_manager.tremos_check_time;
                gs_unusual_moving_thresh_during_time = plat_conf.gsensor_manager.unusual_move_check_time;

                save_platform_config(&plat_conf);
                
            }
            break;
        case DOWN_LINK_CMD_GSENSOR_DRIVER: // Gsensor-driver设置
            CHECK_DATA_MIN_LEN(6);
            if (data_len == 6) // 结构体数据为6
            {
                ret = swei_deal_gsensor_driver_data(data);
            } else {
                ret = CMD_FAILURE;
            }
            if (ret == CMD_SUCCESS) {
                //0-255
                sensor_wakeup_motion_accel_threshold_set(plat_conf.gsensor_driver.interrupt_threshold);

                //3-12
                if(0 == fw_gsensor_set_measure_range(plat_conf.gsensor_driver.measure_range) ) {
                    get_gsensor_local_run_config()->measure_range = plat_conf.gsensor_driver.measure_range;
                }

                //8-10
                int frequecy_val = 100 * (2^(plat_conf.gsensor_driver.sample_frequecy - 8));
                if(0 ==  fw_gsensor_set_sampled_frequency(frequecy_val) ) {
                    get_gsensor_local_run_config()->sample_frequecy = frequecy_val;
                }

                //1-100?
                get_gsensor_local_run_config()->reading_count = plat_conf.gsensor_driver.reading_count;

                //0-1000
                get_gsensor_local_run_config()->interval = plat_conf.gsensor_driver.thread_interval;

                /* measure_range 改变需要重新设置sensitivity数值 */
                tbox_gsensor_set_threshold(plat_conf.common.shake_sensitivity);

                save_platform_config(&plat_conf);

            }
            
            break;
        case DOWN_LINK_CMD_VOLUME: // 设备TBOX声音大小 1-5
            CHECK_DATA_MIN_LEN(1);
            ret = swei_deal_same_uint8_data(1, 5, data[0], &plat_conf.common.sound_volume);
            break;
        default: // 没有别的指令码
            log_e("platform downlink cmd_id[%d] err!", cmd_id);
            ret = CMD_NOT_SUPPORT;
            break;
    }

    if (ret == CMD_SUCCESS) {
        // 更新文件
        ret = save_platform_config(&plat_conf);
        if (ret == 0)
            ret = CMD_SUCCESS;
        else if (ret < 0)
            ret = CMD_FAILURE;
    }
    return ret;
}

/**
 * @brief 配置信息类别
 */
typedef enum {
    CONFIG_TYPE_IDLE = 0,
    CONFIG_TYPE_NORMAL,          // 常规配置信息上报
    CONFIG_TYPE_GSENSOR_MANAGER, // Gsensor管理配置信息
    CONFIG_TYPE_GSENSOR_DRIVER,  // Gsensor驱动配置信息
    CONFIG_TYPE_MAX,
} config_type_e;

config_type_e _cfg_rpt_step = CONFIG_TYPE_NORMAL;
uint8_t _report_finish      = false;

/**
 * @brief 打包配置信息，依赖于配置信息上报登记
 * @param  data             My Param doc
 * @param  data_len         My Param doc
 * @return int32_t
 */
int32_t swei_packet_config_data(uint8_t *data, uint16_t data_len)
{
    int32_t ret_len = 0;
    common_msg_st msg;

    memset(&msg, 0, sizeof(msg));

    switch (_cfg_rpt_step) {
        case CONFIG_TYPE_IDLE: {
            log_i("config report idle!\r\n");
        } break;

        case CONFIG_TYPE_NORMAL: {
            // package the normal config packet
            msg.msg_type = CONFIG_TYPE_NORMAL;
            /* 封装消息 */
            ret_len = swei_package_protocol_msg(&msg, NULL, NET_PROTOCOL_ID_UPLOAD_CONFIG_INFO, data);
            if (ret_len <= 0) {
                log_e("tbox package request fail, ret_len = %d", ret_len);
                return 0;
            } else {
                log_i("get nodmal config data!\r\n");
            }
        } break;

        case CONFIG_TYPE_GSENSOR_MANAGER: {
            // package the gsensor manager config packet
            // 上传Gsensor-manager配置信息
            msg.msg_type = CONFIG_TYPE_GSENSOR_MANAGER;
            /* 封装消息 */
            ret_len = swei_package_protocol_msg(&msg, NULL, NET_PROTOCOL_ID_UPLOAD_CONFIG_INFO, data);
            if (ret_len <= 0) {
                log_e("tbox package request fail, ret_len = %d", ret_len);
                return 0;
            } else {
                log_i("get gsensor manager config data!\r\n");
            }
        } break;

        case CONFIG_TYPE_GSENSOR_DRIVER: {
            // package the gsensor driver config packet
            // 上传Gsensor-driver配置信息
            msg.msg_type = CONFIG_TYPE_GSENSOR_DRIVER;
            /* 封装消息 */
            ret_len = swei_package_protocol_msg(&msg, NULL, NET_PROTOCOL_ID_UPLOAD_CONFIG_INFO, data);
            if (ret_len <= 0) {
                log_e("tbox package request fail, ret_len = %d", ret_len);
                return 0;
            } else {
                log_i("get gsensor driver config data!\r\n");
            }
        } break;

        default:
            _report_finish = true;
            break;
    }

    return ret_len;
}

/**
 * @brief 判断配置上报是否结束
 * @return int32_t
 */
int32_t swei_config_report_finish(void)
{
    return _report_finish ? true : false;
}

/**
 * @brief 配置上报内容
 */
void swei_config_report_trigger_next(void)
{
    _cfg_rpt_step++;
}

/**
 * @brief 重新触发配置上报
 */
void swei_config_report_start(void)
{
    _cfg_rpt_step  = CONFIG_TYPE_NORMAL;
    _report_finish = false;
}

/**
 * @brief 设置激活状态
 * @param  act       My Param doc
 * @return int32_t   <= 0 成功, > 0 错误码
 */
int32_t swei_config_set_activated(uint8_t act)
{
    int ret = 0;

    // 更新文件
    ret = save_platform_config(&plat_conf);
    if (0 == ret)
        plat_conf.activated = act;

    return ret;
}

/**
 * @brief 判断设备是否激活
 * @return uint8_t
 */
uint8_t swei_is_active(void)
{
    return (0 == plat_conf.activated ? false : true);
}
